package com.xbongbong.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.admin.domain.entity.RaidersCorpEntity;
import com.xbongbong.admin.domain.entity.RaidersCorpScoreEntity;
import com.xbongbong.admin.domain.entity.RaidersEntity;
import com.xbongbong.admin.domain.entity.RaidersScoreEntity;
import com.xbongbong.admin.domain.entity.ext.RaidersCorpEntityExt;
import com.xbongbong.admin.help.RaidersHelp;
import com.xbongbong.admin.model.RaidersCorpModel;
import com.xbongbong.admin.model.RaidersCorpScoreModel;
import com.xbongbong.admin.model.RaidersModel;
import com.xbongbong.admin.model.RaidersScoreModel;
import com.xbongbong.admin.pojo.PointPojo;
import com.xbongbong.admin.pojo.RaidersCorpCountListPojo;
import com.xbongbong.admin.pojo.StepInfoPojo;
import com.xbongbong.admin.pojo.dto.RaidersCorpCountDTO;
import com.xbongbong.admin.pojo.dto.RaidersCorpCountListDTO;
import com.xbongbong.admin.pojo.dto.RaidersCorpScoreDTO;
import com.xbongbong.admin.pojo.dto.RaidersScoreDTO;
import com.xbongbong.admin.pojo.dto.RaidersStatusGetDTO;
import com.xbongbong.admin.pojo.vo.RaidersCorpCountListVO;
import com.xbongbong.admin.pojo.vo.RaidersCorpCountVO;
import com.xbongbong.admin.pojo.vo.RaidersCorpScoreVO;
import com.xbongbong.admin.pojo.vo.RaidersScoreVO;
import com.xbongbong.admin.pojo.vo.RaidersStatusGetVO;
import com.xbongbong.admin.service.RaidersCorpService;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.ReflectHelper;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.RaidersConstant;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.RaidersErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.raiders.enums.RaidersFinishEnum;
import com.xbongbong.pro.enums.raiders.enums.RaidersPointChildEnum;
import com.xbongbong.pro.enums.raiders.enums.RaidersScoreLevelEnum;
import com.xbongbong.pro.enums.raiders.enums.RaidersStepEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 攻略绑定公司相关
 *
 * @author 徐俊杰
 * @version v1.0
 * @date 2019/9/25 20:32
 * @since v1.0
 */
@Service("raidersCorpService")
public class RaidersCorpServiceImpl implements RaidersCorpService {

    private static final Logger LOG = LoggerFactory.getLogger(RaidersCorpServiceImpl.class);

    @Resource
    private RaidersCorpModel raidersCorpModel;
    @Resource
    private RaidersModel raidersModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private RaidersScoreModel raidersScoreModel;
    @Resource
    private RaidersHelp raidersHelp;
    @Resource
    private RaidersCorpScoreModel raidersCorpScoreModel;
    @Resource
    private CompanyConfigModel companyConfigModel;

    @Override
    public RaidersCorpScoreVO score(RaidersCorpScoreDTO raidersCorpScoreDTO) throws XbbException {
        try {
            RaidersCorpScoreEntity raidersCorpScore = raidersCorpScoreModel.getByCorpid(raidersCorpScoreDTO.getCorpid());
            int totalScore = (raidersCorpScore == null) ? 0: raidersCorpScore.getTotalScore();
            RaidersScoreLevelEnum level = RaidersScoreLevelEnum.getLevel(totalScore);
            return new RaidersCorpScoreVO(totalScore, level.getLevel(), level.getLevelMin(), level.getLevelMax());
        } catch (Exception e) {
            LOG.error("获取公司总分报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public RaidersCorpCountListVO countList(RaidersCorpCountListDTO raidersCorpCountListDTO) throws XbbException {
        try {
            //缓存
            String listValue = paasRedisHelper.getValue(RedisPrefixConstant.RAIDERS_CORP_COUNT_LIST, RedisPrefixConstant.RAIDERS_CORP_COUNT_LIST);
            List<RaidersCorpCountListPojo> redisList = JSON.parseArray(listValue, RaidersCorpCountListPojo.class);
            if (redisList != null) {
                return new RaidersCorpCountListVO(redisList);
            }
            //已发布的攻略id列表
            List<Long> publishRaidersIdList = raidersModel.getPublishRaidersIdList();
            //获取攻略对应公司数（只获取已发布的攻略）
            Map<String, Object> raidersCorpMap = new HashMap<>(3);
            raidersCorpMap.put("del", DelEnum.NORMAL.getDel());
            raidersCorpMap.put("raidersIdIn", publishRaidersIdList);
            raidersCorpMap.put("orderByStr", "corpCount desc");
            List<RaidersCorpEntityExt> raidersCorpEntityExtList = raidersCorpModel.getCorpCount(raidersCorpMap);
            //获取攻略名称
            Set<Long> raidersIdIn = new HashSet<>();
            for (RaidersCorpEntityExt entityExt : raidersCorpEntityExtList) {
                Long raidersId = entityExt.getRaidersId();
                raidersIdIn.add(raidersId);
            }
            Map<String, Object> raidersMap = new HashMap<>(3);
            raidersMap.put("columns", "id, name");
            raidersMap.put("del", DelEnum.NORMAL.getDel());
            raidersMap.put("idIn", raidersIdIn);
            List<RaidersEntity> raidersList = raidersModel.findEntitys(raidersMap);
            Map<Long, String> raidersIdNameMap = new HashMap<>(raidersList.size());
            for (RaidersEntity raiders : raidersList) {
                raidersIdNameMap.put(raiders.getId(), raiders.getName());
            }
            //封装回参
            List<RaidersCorpCountListPojo> list = new ArrayList<>();
            for (RaidersCorpEntityExt entityExt : raidersCorpEntityExtList) {
                Long raidersId = entityExt.getRaidersId();
                Integer corpCount = entityExt.getCorpCount();
                String corpCountStr = StringUtil.formatDouble(corpCount, "#,##0");
                String name = raidersIdNameMap.getOrDefault(raidersId, "");
                String memo = String.format(I18nMessageUtil.getMessage(RaidersConstant.RAIDERS_CORP_COUNT_TITLE), name);
                RaidersCorpCountListPojo pojo = new RaidersCorpCountListPojo(raidersId, name, corpCountStr, memo);
                list.add(pojo);
            }
            paasRedisHelper.setValue(RedisPrefixConstant.RAIDERS_CORP_COUNT_LIST, RedisPrefixConstant.RAIDERS_CORP_COUNT_LIST, JSON.toJSONString(list), TimeConstant.SECONDS_TWO_HOURS);
            return new RaidersCorpCountListVO(list);
        } catch (Exception e) {
            LOG.error("获取攻略关联公司数列表报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public RaidersCorpCountVO count(RaidersCorpCountDTO raidersCorpCountDTO) throws XbbException {
        try {
            Map<String, Object> raidersCorpMap = new HashMap<>(2);
            raidersCorpMap.put("del", DelEnum.NORMAL.getDel());
            Integer raidersCorpCount = raidersCorpModel.getRaidersCorpCount(raidersCorpMap);
            String raidersCorpCountStr = StringUtil.formatDouble(raidersCorpCount, "#,##0");
            return new RaidersCorpCountVO(raidersCorpCountStr);
        } catch (Exception e) {
            LOG.error("获取攻略关联公司数报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public RaidersScoreVO getScore(RaidersScoreDTO raidersScoreDTO) throws XbbException {
        try {
            //获取攻略关联公司数据
            Long raidersId = raidersScoreDTO.getId();
            String corpid = raidersScoreDTO.getCorpid();
            /**********验证过滤攻略权限：获取攻略实体，并过滤掉已删除、未发布的攻略**********/
            RaidersEntity raiders = raidersHelp.getRaidersEntity(corpid, raidersId, I18nMessageUtil.getMessage(CommonConstant.VIEW));
            /**********获取攻略公司关系实体，如果不存在或锁定中，则不能操作**********/
            RaidersCorpEntity raidersCorp = raidersHelp.getRaidersCorpEntity(corpid, raidersId);
            /**********处理得分**********/
            String step = raidersScoreDTO.getStep();
            RaidersStepEnum stepEnum = RaidersStepEnum.getByStep(step);
            //验证该步骤是否在枚举中存在
            if (RaidersStepEnum.UNKNOWN == stepEnum) {
                throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800005, RaidersErrorCodeEnum.API_ERROR_800005.getMsg(), I18nMessageUtil.getMessage(I18nStringConstant.RAIDERS_STEP));
            }
            String userId = raidersScoreDTO.getUserId();
            Integer thisScore;
            String memo;
            if (stepEnum == RaidersStepEnum.OPERATION) {
                //实操步骤
                Integer pointKey = raidersScoreDTO.getPointKey();
                RaidersPointChildEnum pointEnum = RaidersPointChildEnum.getByPointKey(pointKey);
                if (RaidersPointChildEnum.UNKNOWN == pointEnum) {
                    throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800028, RaidersErrorCodeEnum.API_ERROR_800028.getMsg(), I18nMessageUtil.getMessage(I18nStringConstant.PRACTICAL_FUNCTION_POINTS));
                }
                thisScore = disposeOperationStep(raidersCorp, raiders, pointKey, stepEnum);
                String pointTitle = raidersHelp.getPointTitle(raiders.getPoint(), pointKey);
                memo = String.format(I18nMessageUtil.getMessage(RaidersConstant.FINISH_STEP_OPERATION_POINT), raiders.getName(), stepEnum.getName(), pointTitle);
            } else {
                //一般步骤
                thisScore = disposeNormalStep(raiders, raidersCorp, stepEnum);
                memo = String.format(I18nMessageUtil.getMessage(RaidersConstant.FINISH_STEP), raiders.getName(), stepEnum.getName());
            }
            //插入raidersScore：积分流水
            RaidersScoreEntity raidersScore = new RaidersScoreEntity(corpid, userId, thisScore, memo);
            raidersScoreModel.insert(raidersScore);
            //添加或更新公司总得分
            addCorpTotalScore(corpid, thisScore, userId);
            return new RaidersScoreVO();
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("获得积分报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public RaidersStatusGetVO indexCardGet(RaidersStatusGetDTO raidersStatusGetDTO) throws XbbException {
        String corpid = raidersStatusGetDTO.getCorpid();
        String configAlias = CompanyConfigEnum.RAIDERS.getAlias();
        try {
            CompanyConfigEntity companyConfig = companyConfigModel.getByConfigAlias(configAlias, corpid);
            String status = "0";
            if (companyConfig != null) {
                status = companyConfig.getConfigValue();
            }
            return new RaidersStatusGetVO(Integer.valueOf(status));
        } catch (Exception e) {
            LOG.error("获得公司是否开启价值攻略报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

    }

    /**
     * 处理实操步骤
     *
     * @param raidersCorp raiders_corp
     * @param raiders 攻略
     * @param pointKey 功能点编号
     * @param stepEnum 该步骤的枚举值
     * @return java.lang.Integer
     * @throws
     * @author 徐俊杰
     * @date 2019/10/15 17:34
     * @since v1.0
     */
    private Integer disposeOperationStep(RaidersCorpEntity raidersCorp, RaidersEntity raiders, Integer pointKey, RaidersStepEnum stepEnum) throws XbbException {
        //处理raiders_corp的point_state
        PointPojo pointPojo = new PointPojo(pointKey, RaidersFinishEnum.FINISH.getCode());
        JSONArray pointStateArray = raidersCorp.getPointState();
        //防止重复插入
        for (int i = 0; i < pointStateArray.size(); i++) {
            JSONObject pointState = pointStateArray.getJSONObject(i);
            if (Objects.equals(pointState.getIntValue("pointKey"), pointKey)) {
                throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800020, RaidersErrorCodeEnum.API_ERROR_800020.getMsg(), I18nMessageUtil.getMessage(I18nStringConstant.FUNCTION_POINTS), I18nMessageUtil.getMessage(CommonConstant.COMPLETE), I18nMessageUtil.getMessage(CommonConstant.COMPLETE));
            }
        }
        pointStateArray.add(pointPojo);
        //获得raiders的operation中的score
        JSONObject stepJSON = raiders.getOperation();
        //步骤如果关闭，则无法操作
        if (raidersHelp.checkStepClose(stepJSON)) {
            throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800021, RaidersErrorCodeEnum.API_ERROR_800021.getMsg(), I18nMessageUtil.getMessage(I18nStringConstant.SCORE));
        }
        int score = stepJSON.getIntValue("score");
        Set<Integer> raidersCorpPointKeySet = getPointKeySet(pointStateArray);
        //获得raiders中的point
        JSONArray pointArray = raiders.getPoint();
        Set<Integer> raidersPointKeySet = getPointKeySet(pointArray);
        //获得raiders_corp中的step_score
        JSONArray stepScoreArray = raidersCorp.getStepScore();
        Integer pointScore = 0;
        if (raidersPointKeySet.contains(pointKey)) {
            //比较raiders_corp的point_state是否包含了所有raiders的point
            if (raidersCorpPointKeySet.containsAll(raidersPointKeySet)) {
                //完成最后一个功能点
                pointScore = disposeOperationLastPoint(raidersCorp, raiders, stepScoreArray, score, stepEnum);
            } else {
                //完成一个功能点
                pointScore = disposeOperationOnePoint(raidersCorp, stepScoreArray, score, raidersPointKeySet, stepEnum);
            }
            //处理攻略是否完成
            raidersHelp.disposeRaidersFinish(raiders, raidersCorp, stepScoreArray);
            //功能点已在上面处理过
            raidersCorpModel.update(raidersCorp);
        } else {
            throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800032, RaidersErrorCodeEnum.API_ERROR_800032.getMsg(), I18nMessageUtil.getMessage(I18nStringConstant.SCORE));
        }
        return pointScore;
    }

    /**
     * 从功能点JSONArray中获取pointKeySet
     *
     * @param pointArray 功能点JSONArray
     * @return java.util.Set<java.lang.Integer>
     * @author 徐俊杰
     * @date 2019/9/30 9:34
     * @since v1.0
     */
    private Set<Integer> getPointKeySet(JSONArray pointArray) {
        Set<Integer> pointKeySet = new HashSet<>();
        for (int i = 0; i < pointArray.size(); i++) {
            JSONObject itemJSON = pointArray.getJSONObject(i);
            int pointKey = itemJSON.getIntValue("pointKey");
            pointKeySet.add(pointKey);
        }
        return pointKeySet;
    }

    /**
     * 处理实操步骤得分中是最后一个功能点的情况
     *
     * @param raidersCorp raiders_corp
     * @param raiders 攻略
     * @param stepScoreArray raiders_corp中的step_score
     * @param score raiders的operation中的score：即实操的总分
     * @return java.lang.Integer
     * @author 徐俊杰
     * @date 2019/10/15 16:45
     * @since v1.0
     */
    private Integer disposeOperationLastPoint(RaidersCorpEntity raidersCorp, RaidersEntity raiders, JSONArray stepScoreArray, Integer score, RaidersStepEnum stepEnum) {
        //处理步骤得分step_score
        Integer pointScore = 0;
        stepScoreOperation(stepScoreArray, stepEnum, pointScore);
        for (int i = 0; i < stepScoreArray.size(); i++) {
            JSONObject stepScoreJSON = stepScoreArray.getJSONObject(i);
            String stepName = stepScoreJSON.getString("step");
            if (Objects.equals(stepName, RaidersStepEnum.OPERATION.getStep())) {
                Integer stepScore = stepScoreJSON.getInteger("score");
                //最后一步得到剩余分
                if (stepScore < score) {
                    //不能得0分或负分
                    pointScore = score - stepScore;
                    //该实操全部完成，得到实操步骤的总分
                    stepScore = score;
                }
                stepScoreJSON.put("score", stepScore);
                stepScoreJSON.put("finish", RaidersFinishEnum.FINISH.getCode());
                break;
            }
        }
        //处理总分
        Integer totalScore = raidersCorp.getTotalScore();
        totalScore += pointScore;
        raidersCorp.setTotalScore(totalScore);
        //这次得分
        return pointScore;
    }

    /**
     * 判断当前步骤是否已经加入了raiders_corp的step_score字段
     * 如果还没加入，则加入
     *
     * @param stepScoreArray raiders_corp的step_score字段
     * @param stepEnum 当前得分步骤
     * @param pointScore 当前得分
     * @author 徐俊杰
     * @date 2019/10/16 13:41
     * @since v1.0
     */
    private void stepScoreOperation(JSONArray stepScoreArray, RaidersStepEnum stepEnum, Integer pointScore) {
        //初步处理step_score，如果step_score还没有加入当前step则加入
        boolean stepExist = false;
        for (int i = 0; i < stepScoreArray.size(); i++) {
            JSONObject stepScoreJSON = stepScoreArray.getJSONObject(i);
            StepInfoPojo stepInfoPojo = JSONObject.toJavaObject(stepScoreJSON, StepInfoPojo.class);
            if (Objects.equals(stepInfoPojo.getStep(), stepEnum.getStep())) {
                stepExist = true;
                break;
            }
        }
        if (!stepExist) {
            JSONObject stepJSON = new JSONObject();
            stepJSON.put("step", stepEnum.getStep());
            stepJSON.put("score", pointScore);
            stepJSON.put("finish", RaidersFinishEnum.FINISH_UN.getCode());
            stepScoreArray.add(stepJSON);
        }
    }

    /**
     * 实操中一个功能点得分
     *
     * @param raidersCorp raiders_corp
     * @param stepScoreArray raiders_corp中的step_score
     * @param score raiders的operation中的score
     * @param raidersPointKeySet raiders中的point
     * @param stepEnum 该步骤枚举
     * @return java.lang.Integer
     * @author 徐俊杰
     * @date 2019/10/15 17:06
     * @since v1.0
     */
    private Integer disposeOperationOnePoint(RaidersCorpEntity raidersCorp, JSONArray stepScoreArray, Integer score, Set<Integer> raidersPointKeySet, RaidersStepEnum stepEnum) {
        Integer pointScore = score / raidersPointKeySet.size();
        //实操步骤已得分
        int oldOperationScore = acquireOperationScore(stepScoreArray);
        //已得分大于等于应得分
        if (oldOperationScore >= score) {
            pointScore = 0;
            //已得分+该功能点分大于等于应得分
        } else if ((oldOperationScore + pointScore) >= score) {
            pointScore = score - oldOperationScore;
        }
        //处理总分
        Integer totalScore = raidersCorp.getTotalScore();
        totalScore += pointScore;
        raidersCorp.setTotalScore(totalScore);
        //处理步骤得分
        //已存在于raiders_corp中step_score的步骤名列表
        List<String> stepNameList = new ArrayList<>();
        for (Object object : stepScoreArray) {
            JSONObject stepScoreObj = (JSONObject) object;
            String stepName = stepScoreObj.getString("step");
            stepNameList.add(stepName);
        }
        if (!stepNameList.contains(RaidersStepEnum.OPERATION.getStep())) {
            //如果实操步骤还未加入，则加入一个部分完成的实操步骤
            StepInfoPojo stepInfoPojo = new StepInfoPojo(stepEnum.getStep(), pointScore, RaidersFinishEnum.FINISH_PART.getCode());
            stepScoreArray.add(stepInfoPojo);
        } else {
            //如果实操步骤已经加入，则增加step_score中实操步骤的score
            for (int i = 0; i < stepScoreArray.size(); i++) {
                JSONObject stepScoreJSON = stepScoreArray.getJSONObject(i);
                String stepName = stepScoreJSON.getString("step");
                if (Objects.equals(stepName, RaidersStepEnum.OPERATION.getStep())) {
                    Integer operationScore = stepScoreJSON.getIntValue("score");
                    operationScore += pointScore;
                    stepScoreJSON.put("score", operationScore);
                    stepScoreJSON.put("finish", RaidersFinishEnum.FINISH_PART.getCode());
                    break;
                }
            }
        }
        //这次得分
        return pointScore;
    }

    /**
     * 攻略一般步骤得分
     * 除实操步骤外
     *
     * @param raiders 攻略
     * @param raidersCorp raiders_corp
     * @param stepEnum 步骤枚举
     * @return java.lang.Integer
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/10/15 16:38
     * @since v1.0
     */
    private Integer disposeNormalStep(RaidersEntity raiders, RaidersCorpEntity raidersCorp, RaidersStepEnum stepEnum) throws XbbException {
        try {
            //反射获取需要的字段
            JSONObject stepJSON = (JSONObject) ReflectHelper.valueGet(raiders, stepEnum.getStep());
            //步骤如果关闭，则无法操作
            if (raidersHelp.checkStepClose(stepJSON)) {
                throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800021, RaidersErrorCodeEnum.API_ERROR_800021.getMsg(), I18nMessageUtil.getMessage(I18nStringConstant.SCORE));
            }
            //这次得分
            Integer thisScore = stepJSON.getIntValue("score");
            updateStepScore(raidersCorp, raiders, thisScore, stepEnum);
            return thisScore;
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("RaidersCorpServiceImpl.disposeNormalStep error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }


    /**
     * 更新raidersCorp(total_score,step_score,finish)：需防止重复得分
     * 一般步骤（不包含实操）
     *
     * @param raidersCorp 攻略公司绑定记录
     * @param raiders 攻略
     * @param score 分数
     * @param stepEnum 步骤
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/9/30 10:04
     * @since v1.0
     */
    private void updateStepScore(RaidersCorpEntity raidersCorp, RaidersEntity raiders, Integer score, RaidersStepEnum stepEnum) throws XbbException {
        //处理总分
        Integer totalScore = raidersCorp.getTotalScore();
        totalScore += score;
        raidersCorp.setTotalScore(totalScore);
        //处理步骤得分（防止重复得分）
        JSONArray stepScoreArray = raidersCorp.getStepScore();
        //是否是新插入的步骤
        boolean flag = true;
        for (int i = 0; i < stepScoreArray.size(); i++) {
            JSONObject stepScore = stepScoreArray.getJSONObject(i);
            String step = stepScore.getString("step");
            Integer finish = stepScore.getIntValue("finish");
            if (Objects.equals(step, stepEnum.getStep())) {
                if (Objects.equals(finish, 1)) {
                    throw new XbbException(RaidersErrorCodeEnum.API_ERROR_800020, RaidersErrorCodeEnum.API_ERROR_800020.getMsg(), stepEnum.getName(), I18nMessageUtil.getMessage(CommonConstant.COMPLETE), I18nMessageUtil.getMessage(CommonConstant.COMPLETE));
                }
                flag = false;
                //否则置为已完成
                stepScore.put("finish", 1);
            }
        }
        if (flag) {
            StepInfoPojo stepInfoPojo = new StepInfoPojo(stepEnum.getStep(), score, RaidersFinishEnum.FINISH.getCode());
            stepScoreArray.add(stepInfoPojo);
        }
        //处理攻略是否完成
        raidersHelp.disposeRaidersFinish(raiders, raidersCorp, stepScoreArray);
        //更新
        raidersCorpModel.update(raidersCorp);
    }

    /**
     * 添加或更新公司总得分
     *
     * @param corpid 公司id
     * @param score 得分
     * @param userId 使用人
     * @throws XbbException 数据库操作异常
     * @author 徐俊杰
     * @date 2019/10/15 9:38
     * @since v1.0
     */
    private void addCorpTotalScore(String corpid, Integer score, String userId) throws XbbException {
        if (score <= 0) {
            //只增加分值，负数或0则不处理
            return;
        }
        RaidersCorpScoreEntity raidersCorpScoreEntity = raidersCorpScoreModel.getByCorpid(corpid);
        if (raidersCorpScoreEntity == null) {
            //如果没有该公司的数据，就插入一条
            raidersCorpScoreEntity = new RaidersCorpScoreEntity(corpid, userId, score, score);
            raidersCorpScoreModel.insert(raidersCorpScoreEntity);
        } else {
            //如果有该公司的数据，就更新分值
            //总分
            Integer totalScore = raidersCorpScoreEntity.getTotalScore();
            totalScore += score;
            raidersCorpScoreEntity.setTotalScore(totalScore);
            //剩余分
            Integer surplusScore = raidersCorpScoreEntity.getSurplusScore();
            surplusScore += score;
            raidersCorpScoreEntity.setSurplusScore(surplusScore);
            raidersCorpScoreModel.update(raidersCorpScoreEntity);
        }
    }

    /**
     * 获取实操步骤已得分（若还没有进行实操则返回0）
     *
     * @param stepScoreArray 步骤得分情况
     * @return int
     * @author 徐俊杰
     * @date 2019/11/15 11:36
     * @since v1.0
     */
    private int acquireOperationScore(JSONArray stepScoreArray) {
        int operationScore = 0;
        for (int i = 0; i < stepScoreArray.size(); i++) {
            JSONObject stepScoreJSON = stepScoreArray.getJSONObject(i);
            String stepName = stepScoreJSON.getString("step");
            if (Objects.equals(stepName, RaidersStepEnum.OPERATION.getStep())) {
                operationScore = stepScoreJSON.getIntValue("score");
                break;
            }
        }
        return operationScore;
    }
}
